const Op = require('sequelize').Op;
const fs = require('fs');
const moment = require('moment');
const path = require('path');
const db = require('../model/index');
const Notification = db.models.Notification;
const User = db.models.User;
const WorkingSchedule = db.models.WorkingSchedule;
const Equipment = db.models.Equipment;

class NotificationController {
  async getNotificationList(ctx) {
    const type = 1; // 是文件
    let {limit, page, sStr} = ctx.request.body;
    limit = limit || 10;
    page = page || 1;
    let where = {
      type,
    };
    if(sStr) {
      where = Object.assign(where, {
        title: {
          [Op.like]: `%${sStr}%`
        }
      });
    }
    let totalCount = await Notification.count({
      where,
    });
    let fileList = await Notification.findAll({
      where,
      limit: limit === -1 ? null : limit,
      offset: limit === -1 ? null : limit * (page - 1),
      order: [
        ['priority', 'DESC'],
        ['updatedAt', 'DESC']
      ]
    });
    fileList = fileList.map((file) => {
      return Object.assign(file.dataValues, {
        isPrivate: !! file.isPrivate,    // 注意，这里由于后端mysql数据库存储的bool类型实际上是0和1，前端Radio等无法正确识别，所以返回前要强制转换成bool
        files: [{
          name: file.filename,
          url: file.downloadUrl,
        }]
      })
    });

    ctx.body = {
      code: 0,
      msg: {
        count: fileList.length,
        totalCount,
        fileList,
      }
    }
  }

  async addNotification(ctx) {
    let user = ctx.user;
    const type = 1; // 是文件
    let { title, files, realFileName, priority } = ctx.request.body;
    priority = priority || 1;
    let downloadUrl = files[0].url;
    let filename = files[0].name;
    await Notification.create({
      title,
      filename,
      downloadUrl,
      realFileName,
      priority,
      UserName: user.username,
      UserId: user.id,
      type,   // 是通知
      createdTime: true,  // 调用set
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async updateNotification(ctx) {
    let { id, title, files, realFileName, priority } = ctx.request.body;
    priority = priority || 1;
    let file = await Notification.findOne({
      where: {
        id,
      }
    });
    if(file && file.realFileName !== realFileName) {
      fs.unlink(path.join(__dirname, '../../files', file.realFileName), (err) => {
        if(err) {
          console.log(err);
        }
      });
    }
    let downloadUrl = files[0].url;
    let filename = files[0].name;
    await Notification.update({
      priority,
      downloadUrl,
      filename,
      title,
      realFileName,
    }, {
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async deleteNotification(ctx) {
    let { id } = ctx.request.body;
    let file = await Notification.findOne({
      where: {
        id
      }
    });
    if(file) {
      fs.unlink(path.join(__dirname, '../../files', file.realFileName), (err) => {
        if(err) {
          console.log(err);
        }
      });
    }
    await Notification.destroy({
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }


  async getFileList(ctx) {
    let user = ctx.user;
    const type = 2; // 是文件
    let { limit, page, sStr } = ctx.request.body;
    limit = limit || 10;
    page = page || 1;
    let where = {
      type,
      [Op.or]: [{
        isPrivate: false,
      }, {
        isPrivate: true,  // 如果是私密文件，只有用户自己能够看到
        UserId: user.id,
      }]
    };
    if(sStr) {
      where = Object.assign({
        title: {
          [Op.like] : `%${sStr}%`
        }
      })
    }
    let totalCount = await Notification.count({
      where
    });
    let fileList = await Notification.findAll({
      where,
      limit: limit === -1 ? null : limit,
      offset: limit === -1 ? null : limit * (page - 1),
      order: [
        ['priority', 'DESC'],
        ['updatedAt', 'DESC']
      ]
    });
    fileList = fileList.map((file) => {
      return Object.assign(file.dataValues, {
        isPrivate: !! file.isPrivate,    // 注意，这里由于后端mysql数据库存储的bool类型实际上是0和1，前端Radio等无法正确识别，所以返回前要强制转换成bool
        files: [{
          name: file.filename,
          url: file.downloadUrl,
        }]
      })
    });

    ctx.body = {
      code: 0,
      msg: {
        count: fileList.length,
        totalCount,
        fileList,
      }
    }
  }

  async addFile(ctx) {
    let user = ctx.user;
    const type = 2; // 是文件
    let { title, files, realFileName, priority, isPrivate } = ctx.request.body;
    priority = priority || 1;
    isPrivate = !! isPrivate;   // 如果没有此请求项目，是公开文件
    let downloadUrl = files[0].url;
    let filename = files[0].name;
    await Notification.create({
      title,
      filename,
      downloadUrl,
      realFileName,
      priority,
      UserName: user.username,
      UserId: user.id,
      isPrivate, // 是否是私密文件
      type,
      createdTime: true,  // 调用set
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async updateFile(ctx) {
    let user = ctx.user;
    let { id, title, files, realFileName, priority, isPrivate } = ctx.request.body;
    priority = priority || 1;
    isPrivate = !! isPrivate;
    let file = await Notification.findOne({
      where: {
        id,
      }
    });
    if(file.UserId !== user.id) {
      ctx.body = {
        code: 100,
        msg: {
          error: '越权操作',
        }
      };
      return;
    }

    if(file && file.realFileName !== realFileName) {
      fs.unlink(path.join(__dirname, '../../files', file.realFileName), (err) => {
        if(err) {
          console.log(err);
        }
      });
    }
    let downloadUrl = files[0].url;
    let filename = files[0].name;
    await Notification.update({
      priority,
      downloadUrl,
      filename,
      title,
      realFileName,
      isPrivate,
    }, {
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }

  async deleteFile(ctx) {
    let user = ctx.user;
    let { id } = ctx.request.body;
    let file = await Notification.findOne({
      where: {
        id
      }
    });
    if(file.UserId !== user.id) {
      ctx.body = {
        code: 100,
        msg: {
          error: '越权操作',
        }
      };
      return;
    }
    if(file) {
      fs.unlink(path.join(__dirname, '../../files', file.realFileName), (err) => {
        if(err) {
          console.log(err);
        }
      });
    }
    await Notification.destroy({
      where: {
        id,
      }
    });
    ctx.body = {
      code: 0,
      msg: {},
    }
  }


  async getDutyList(ctx) {
    let { page, limit } = ctx.request.body;
    page = page || 1;
    limit = limit || -1;

    let teams = await WorkingSchedule.findAll({  // startTime <= now < endTime
      where: {
        startTime: {
          [Op.lte]: new Date()
        },
        endTime: {
          [Op.gt]: new Date()
        }
      }
    });
    teams = teams.map((t) => {
      return t.dataValues.teamName;
    });

    // 再找到当值班组中的所有的用户，分组返回
    let totalCount = await User.count({
      where: {
        teamName: teams,
      },
    });
    let userList = await User.findAll({
      attributes: ['id', 'username', 'teamName', 'isTeamLeader', 'avatar', 'phone', 'email'],
      where: {
        teamName: teams,
      },
      order: [
        ['teamName', 'ASC']
      ],
      limit: limit === -1 ? undefined: limit,
      offset: limit === -1 ? undefined: (page - 1) * limit,
    });

    ctx.body = {
      code: 0,
      msg: {
        totalCount,
        userList,
      },
    }
  }

  async getEquipmentState(ctx) {
    let { page, limit } = ctx.request.body;
    let goodCount = await Equipment.count({
      where: {
        state: true,
      }
    });
    let badCount = await Equipment.count({
      where: {
        state: false,
      }
    });
    let badList = await Equipment.findAll({
      where: {
        state: false,
      },
      limit: limit === -1 ? undefined : limit,
      offset: limit === -1 ? undefined : (page - 1) * limit,
    });

    ctx.body = {
      code: 0,
      msg: {
        goodCount,
        badCount,
        badList,
      }
    }
  }
}

module.exports = new NotificationController();
